package jers.impl;

import java.rmi.RemoteException;

import jers.Callback;
import jers.Result;
import jers.util.Daemon;

/**
 * Classe que decora a interface {@link Callback} para redefinir seu 
 * comportamento adicionando o recurso de espera da thread pela 
 * invocacao da callback.
 * 
 * @author 
 * 		<a href="mailto:felipe.zappala@gmail.com">
 * 			Luis Felipe Zappala
 * 		</a> [ <a href="http://lncc.br/ist">ISTCC-P</a> / 2009 ]
 */
class WaiterCallback implements Callback {

	private static final long serialVersionUID = -6760585799518808269L;
	private final Callback decorated;
	private final Daemon waiter;
	
	
	public WaiterCallback(Callback decorated) {
		this.decorated = decorated;
		this.waiter = new WaiterThreadDaemon();
	}
	
	public void call(Result result) throws RemoteException {
		waiter.start();
		decorated.call(result);
		waiter.stop();
	}

	/**
	 * Daemon de espera 
	 */
	class WaiterThreadDaemon implements Daemon, Runnable {

		private boolean running = false;
		private Thread thread;
		
		public boolean isStarted() {
			return running;
		}

		public boolean isStopped() {
			return !running;
		}

		public void start() {
			this.stop();
			this.running = true;
			this.thread = new Thread(this);
			this.thread.start();
		}

		public void stop() {
			this.running = false;
			if (this.thread != null) {
				this.thread.interrupt();
			}
		}

		public void run() {
			while(running) {
				try {
					Thread.sleep(Long.MAX_VALUE);
				} catch (InterruptedException e) {
					// Nada faz...
				}
			}
		}
		
	}
}
